import LXCOM from '../common/common.js'
import baseunitgrah from './baseunitgrah.js'
import { CoordTRFUtil } from '../common/tools/coordtool.js'
import ActPkg from '../graph/action/rectaction.js'
import GlobalConst from '../common/globalConst.js'
var global = GlobalConst.GlobalConst;

import UtilFuncs from '../common/tools/utilfuncs.js'
var funcs = UtilFuncs.UtilFuncs;
import Coord from '../common/struct/coord.js'
import {FillUtil} from '../graph/paintutil/fillutil.js'
import {LGXEnums}  from '../common/sysenum.js'

import {Strokeutil} from '../graph/paintutil/strokeutil.js'

import RectPkg from '../common/struct/basestruct/rectangle.js'
import coord from '../common/struct/coord.js'
var Rectangle = RectPkg.Rectangle;

import { GlobalVar } from '../common/globalvar.js'

var testCoordFlag = false;

class RectGraph extends baseunitgrah.BaseUnitGraph {
    constructor(gid) {
        super(gid);
        var p = new Coord.MultiPos();
        super._position = new coord.MultiPos;
        this.setPos(p);
        var action = new ActPkg.RectGraphAction(this);
        this.setActionSvc(action);
        this.m_graphType = LGXEnums.LGXGraphType.RectGraph_type;
        this.titleZoneFlag = false;
        this.symbolEdgeFlag = false;
        let position = this.getPos();
        position.addPoint({x:-60,y:40});
        position.addPoint({x:-60,y:-40});
        position.addPoint({x:60,y:-40});
        position.addPoint({x:60,y:40});
    }

    display(map, mapInfo,forClip) {
        // console.log("rect display****************************");
        let container = this.getContainer();
        if (this.symbolEdgeFlag && container) {
            let supSymbol = container.getSymbol();
            if (supSymbol && supSymbol.getMoldActionType() == LGXEnums.moldActionType.item) {
                return;
            }
        }
        var scaling = mapInfo.getLenthDisScale();
        map.beginPath();
        var cntWorldPT = this.getZone().getCnt();
        var cntScreenPT = CoordTRFUtil.world2Screen(cntWorldPT, mapInfo);

        var ptlst = new Array();
        var position = this.getPos();
        var lenth = position.posList.length;
        var pt = position.posList[0];
        var p0 = CoordTRFUtil.world2Screen(pt, mapInfo);
        let rotv = this.getRadAngle();

        map.save();
        map.moveTo(p0.x, p0.y);
        ptlst.push(p0);
        for (var i = 1; i < lenth; i++) {
            pt = position.posList[i];
            var p = CoordTRFUtil.world2Screen(pt, mapInfo);
            map.lineTo(p.x, p.y);
            ptlst.push(p);
        }
        map.lineTo(p0.x, p0.y);
        map.closePath();

        if (this.m_graphType == LGXEnums.LGXGraphType.MultiSel_Rect_Type) {
            scaling = 1;
        }

        if (!forClip){
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this._fillDef, map, this, mapInfo, false);
        }
        map.restore();

        super.displayGraphScope(map, mapInfo);
        this.displayFeaturePoint(map, mapInfo, ptlst);
    }

    disInSymbol_bak(transformInfo,map, mapInfo,forClip) {
        var scaling = mapInfo.getLenthDisScale();
        map.beginPath();
        var position = this.getPosCopy();
        var lenth = position.posList.length;
        var pt = position.posList[0];
        let spt = CoordTRFUtil.local2Screen(pt, mapInfo);
        var x0 = spt.x;
        var y0 = spt.y;
        map.moveTo(spt.x, spt.y);
        for (var i = 1; i < lenth; i++) {
            pt = position.posList[i];
            spt = CoordTRFUtil.local2Screen(pt, mapInfo);
            map.lineTo(spt.x, spt.y);
        }
        map.lineTo(x0, y0);
        map.closePath();
        if (!forClip){
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this._fillDef, map, this, mapInfo, true,transformInfo);
        }
    }
    disInSymbol(transformInfo,map, mapInfo,forClip) {
        var scaling = mapInfo.getLenthDisScale();
        map.beginPath();
        var position = this.getPosCopy();
        var lenth = position.posList.length;
        var pt = position.posList[0];
        let wpt = CoordTRFUtil.transLocalPt2World(pt, 0, transformInfo);
        let spt = CoordTRFUtil.world2Screen(wpt, mapInfo);
        var x0 = spt.x;
        var y0 = spt.y;
        map.moveTo(spt.x, spt.y);
        for (var i = 1; i < lenth; i++) {
            pt = position.posList[i];
            let wpt = CoordTRFUtil.transLocalPt2World(pt, 0, transformInfo);
            spt = CoordTRFUtil.world2Screen(wpt, mapInfo);
            map.lineTo(spt.x, spt.y);
        }
        map.lineTo(x0, y0);
        map.closePath();
        if (!forClip){
            Strokeutil.active(this._lineDef, this, map, mapInfo);
            FillUtil.active(this._fillDef, map, this, mapInfo, true,transformInfo);
        }
    }

    calScope(mapscale) {
        var position = this.getPos();
        var lenth = position.posList.length;
        if (lenth < 2) {
            return;
        }
        this._zone.clone(position.getZone());
    }

    getLocalZone() {
        let mtx = this.getLocalMatrix();
        let inverseMtx = mtx.Inverse();
        let rect = new LXCOM.LGXRect(0, 0, 0, 0);
        let position = this.getPos();
        let length = position.posList.length;
        for (var i = 0; i < length; i++) {
            let pt = position.posList[i];
            let localPt = inverseMtx.MultT({ x: pt.x, y: pt.y, z: 0 });//求相对于控制图形局部坐标系的局部坐标  
            let x = localPt.x;
            let y = localPt.y;

            if (i == 0) {
                rect.left = x;
                rect.right = x;
                rect.top = y;
                rect.bottom = y;
            }
            rect.left = Math.min(rect.left, x);
            rect.right = Math.max(rect.right, x);
            rect.bottom = Math.min(rect.bottom, y);
            rect.top = Math.max(rect.top, y);
        }
        return rect;
    }

    displayFeaturePoint(map, mapInfo, ptLst) {
        if (!this._selected || mapInfo.paintForGenerateICON) {
            return;
        }
        
        if (this.m_graphType == LGXEnums.LGXGraphType.MultiSel_Rect_Type) {
            super.displayFeaturePoint(map, mapInfo);
        }
        else if (this._selected) {
            super.displayFeaturePoint(map, mapInfo);
            map.save();
            var lenth = ptLst.length;
            for (var i = 0; i < lenth; i++) {
                var point = ptLst[i];
                if (i < lenth - 1) {
                    var nextPoint = ptLst[i + 1];
                    let x = (point.x + nextPoint.x) / 2.0;
                    let y = (point.y + nextPoint.y) / 2.0;
                    super.drawFocusPoint(map, x, y, "#0000ff");
                }
                else {
                    var nextPoint2 = ptLst[0];
                    let x = (point.x + nextPoint2.x) / 2.0;
                    let y = (point.y + nextPoint2.y) / 2.0;
                    super.drawFocusPoint(map, x, y, "#0000ff");
                }
            }
            map.restore();
        }
    }



    distance(tPoint, scaling, mapscale) {
        var position = this.getPos();
        var poscount = position.posList.length;
        if (poscount < 2) {
            return -1;
        }
        if (!super.preCheckInScope(tPoint, scaling)) {
            return -1;
        }
        var cmpGap = super.getSelCmpGap(scaling, mapscale);
        var nMinDis = -1;
        var pPrePos = position.posList[0];
        for (var i = 1; i < poscount; i++) {
            let pCntPos = position.posList[i];
            let dis = funcs.distanceLineSec4Visual(tPoint, pPrePos, pCntPos, scaling);
            if (dis >= 0) {
                if (nMinDis < 0) {
                    nMinDis = dis;
                }
                else if (dis < nMinDis) {
                    nMinDis = dis;
                }
            }
            pPrePos = pCntPos;
        }

        //末尾和头坐标
        let pCntPos = position.posList[0];
        let dis = funcs.distanceLineSec4Visual(tPoint, pPrePos, pCntPos, scaling);
        if (dis >= 0) {
            if (nMinDis < 0) {
                nMinDis = dis;
            }
            else if (dis < nMinDis) {
                nMinDis = dis;
            }
        }

        if (!GlobalVar.easySelMode) {
            if (nMinDis > cmpGap){
                nMinDis = -1;
            }
        }
        else{
            if (this._fillDef.fillStyle != LGXEnums.LGXFillStyle.EMPTY){
                nMinDis = 0;
            }
        }

        return nMinDis;
    }


    calculateSubKind(tPoint, scaling, mapscale) {
        if (!super.preCheckInScope(tPoint, scaling)) {
            return 0;
        }

        var seleKind = 0;
        var position = this.getPos();
        var lenth = position.posList.length;
        if (lenth < 2) {
            return 0;
        }

        var tAbsorbPt = new LXCOM.LGXPoint();
        tAbsorbPt.clone(tPoint);

        var cmpGap = super.getSelCmpGap(scaling, mapscale);

        var lDis = -1;
        var nMinDis = 99;
        var pCntPos = null;
        var pPrePos = position.posList[0];
        for (var i = 1; i < lenth; i++) {
            pCntPos = position.posList[i];
            lDis = funcs.distanceLineSec4Visual(tPoint, pPrePos, pCntPos, scaling);
            if (lDis <= cmpGap && lDis >= 0 && lDis <= nMinDis) {
                nMinDis = lDis;
                tAbsorbPt.clone(tPoint);
                var nConnType = funcs.adsorbPosOnLineSec(tAbsorbPt, pPrePos, pCntPos, scaling);
                if (nConnType % 10 == 0) {
                    seleKind = lenth + 1;
                }
                else {
                    var n = Math.floor(nConnType / 10);
                    seleKind = n + i;
                }
            }
            pPrePos = pCntPos;
        }

        if (seleKind > 0) {
            tPoint.clone(tAbsorbPt);
        }
        if (this._fillDef.fillStyle != LGXEnums.LGXFillStyle.EMPTY){
            seleKind = 5;
        }
        return seleKind;
    }

    movePosOffset(tOffset, modCmdInfo) {
        if (this._selKind < 1) {
            return;
        }
        if (this._selKind == 5) {
            this.translate(tOffset, modCmdInfo.mapscale, false);
        }
    }


    getMainFeaturePTLst(tFeaturePTLst,transformInfo) {
        let position = this.getPosCopy();
        let p0 = position.posList[0];
        position.addPoint(p0);

        var lenth = position.posList.length;
        for (var i = 0; i < lenth; i++) {
            var pt = position.posList[i];
            let featurePT = this.convertPt2World(pt,transformInfo);
            tFeaturePTLst.push({pt:featurePT,kind:LGXEnums.AuxPointKind.end});
        }

        let prePt = position.posList[0];
        for (let i = 1; i < lenth; i++) {
            let pt = position.posList[i];
            let x = (prePt.x + pt.x) / 2;
            let y = (prePt.y + pt.y) / 2;
            let t = { x, y };
            let featurePT = this.convertPt2World(t,transformInfo);
            tFeaturePTLst.push({pt:featurePT,kind:LGXEnums.AuxPointKind.lineMid});
            prePt = pt;
        }
    }

    getSubFeaturePTLst(tFeaturePTLst, mousePoint,transformInfo) {
        let position = this.getPosCopy();
        let p0 = position.posList[0];
        position.addPoint(p0);

        let lenth = position.posList.length;
        let tMayAbsorbPtLst = [];
        let prePt = position.posList[0];
        prePt = this.convertPt2World(prePt,transformInfo);
        for (let i = 1; i < lenth; i++) {
            let nextPt = position.posList[i];
            nextPt = this.convertPt2World(nextPt,transformInfo);
            let vector = funcs.getVector(prePt, nextPt);
            let projPt = funcs.getPointProj2Line(mousePoint, prePt, vector);
            if (projPt && funcs.chkPointOnLineSec(projPt, prePt, nextPt)) {
                let dis = funcs.distancePoint(projPt, mousePoint);
                let t = { dis, pt: projPt };
                tMayAbsorbPtLst.push(t);
            }
            prePt = nextPt;
        }

        //排序
        let sortedList = tMayAbsorbPtLst.sort(function (p1, p2) {
            if ((p1.dis - p2.dis) > 0) {
                return 1;
            }
            else {
                return -1;
            }
        }
        );
        if (sortedList.length) {
            let t = sortedList[0];
            tFeaturePTLst.push({ pt: t.pt, kind: LGXEnums.AuxPointKind.commonPt });
        }
    }

    assignInfo(info) {
        super.assignInfo(info);
        this.setAngle(info.angle);
        this.titleZoneFlag = info.titleZoneFlag;
        this.symbolEdgeFlag = info.symbolEdgeFlag;
    }

    modifyAttribute(info, mapscale) {
        super.modifyAttribute(info,1);
        this.setAngle(info.angle);
        this.titleZoneFlag = info.titleZoneFlag;
        this.symbolEdgeFlag = info.symbolEdgeFlag;
        this.calScope(mapscale);
    }

    toInfo() {
        var info = new Rectangle();
        this.toInfo4InheritClass(info);
        info.strPosition = this.getPos().toString();
        info.angle = this.getAngle();
        info.titleZoneFlag = this.titleZoneFlag;
        info.symbolEdgeFlag = this.symbolEdgeFlag;
        return info;
    }

    getPosCopy() {
        let pos = new Coord.MultiPos();
        pos.clone(this._position);
        return pos;
    }

    getPath() {
        let path = [];
        var position = this.getPos();
        var lenth = position.posList.length;
        for (var i = 0; i < lenth; i++) {
            var pt = position.posList[i];
            path.push({ x: pt.x, y: pt.y });
        }
        return path;
    }

    modifyCoord(propName, propVal, mapscale) {
        var position = this.getPos();
        let rect = position.getZone();

        var lenth = position.posList.length;
        if (propName == "poslist") {
            for (var i = 0; i < lenth; i++) {
                var pt = position.posList[i];
                let jsonObj = propVal[i];
                pt.x = parseFloat(jsonObj.x);
                pt.y = parseFloat(jsonObj.y);
            }
        }
        else if (propName == "cnt") {
            let preCnt = rect.getCnt();
            let x = parseFloat(propVal.x);
            let y = parseFloat(propVal.y);
            let ox = x - preCnt.x;
            let oy = y - preCnt.y;

            for (var i = 0; i < lenth; i++) {
                var pt = position.posList[i];
                pt.x += ox;
                pt.y += oy;
            }
        }
        else if (propName == "lbpt") {
            let w = rect.width();
            let h = rect.height();
            let x = parseFloat(propVal.x);
            let y = parseFloat(propVal.y);

            let p0 = position.posList[0];
            p0.x = x;
            p0.y = y + h;

            let p1 = position.posList[1];
            p1.x = x + w;
            p1.y = y + h;

            let p2 = position.posList[2];
            p2.x = x + w;
            p2.y = y;

            let p3 = position.posList[3];
            p3.x = x;
            p3.y = y;
        }
        else if (propName == "width") {
            let w = parseFloat(propVal);
            let h = rect.height();
            let x = rect.left;
            let y = rect.bottom;

            let p0 = position.posList[0];
            p0.x = x;
            p0.y = y + h;

            let p1 = position.posList[1];
            p1.x = x + w;
            p1.y = y + h;

            let p2 = position.posList[2];
            p2.x = x + w;
            p2.y = y;

            let p3 = position.posList[3];
            p3.x = x;
            p3.y = y;
        }
        else if (propName == "height") {
            let w = rect.width()
            let h = parseFloat(propVal);
            let x = rect.left;
            let y = rect.bottom;

            let p0 = position.posList[0];
            p0.x = x;
            p0.y = y + h;

            let p1 = position.posList[1];
            p1.x = x + w;
            p1.y = y + h;

            let p2 = position.posList[2];
            p2.x = x + w;
            p2.y = y;

            let p3 = position.posList[3];
            p3.x = x;
            p3.y = y;
        }
        this.notifyToObserver();
        this.calScope(mapscale);
    }

    getCoordInfo() {
        let graphPropDef = this.getCoordPropDef();
        let tableData = [];
        let arr = [];
        var position = this.getPos();
        var lenth = position.posList.length;
        for (var i = 0; i < lenth; i++) {
            var pt = position.posList[i];
            arr.push({ x: pt.x, y: pt.y });
        }

        let rect = position.getZone();

        let polistObj = {
            propName: 'poslist',
            propLabel: '顶点列表',
            propValue: arr
        };
        tableData.push(polistObj);

        let cntObj = {
            propName: 'cnt',
            propLabel: '中心',
            propValue: { x: rect.getCnt().x, y: rect.getCnt().y }
        };
        tableData.push(cntObj);

        let leftBotObj = {
            propName: 'lbpt',
            propLabel: '左下角',
            propValue: { x: rect.lbPt().x, y: rect.lbPt().y }
        };
        tableData.push(leftBotObj);

        let widObj = {
            propName: 'width',
            propLabel: '宽',
            propValue: rect.width()
        };
        tableData.push(widObj);

        let hgtObj = {
            propName: 'height',
            propLabel: '高',
            propValue: rect.height()
        };
        tableData.push(hgtObj);

        let tableForm = {
            'tableData': tableData
        };
        return { graphPropDef, tableForm };
    }

    getCoordPropDef() {
        let graphPropDef = {
            'poslist': {
                vtype: global.PtList_CoordType,
                range: { min: 1, max: 10 },
            },
            'lbpt': {
                vtype: global.Pt_CoordType,
                range: { min: 1, max: 10 },
            },
            'cnt': {
                vtype: global.Pt_CoordType,
                range: { min: 1, max: 10 },
            },
            'width': {
                vtype: global.Single_CoordType,
                range: { min: 1, max: 10000 },
            },
            'height': {
                vtype: global.Single_CoordType,
                range: { min: 1, max: 10000 },
            }
        }
        return graphPropDef;
    }

    getDimDatumFeatureLst() {
        let rstArr = [];

        let idkey = 1;
        //图形中心
        {
            let cnt = this.getZone().getCnt();
            let data = { x: cnt.x, y: cnt.y };
            let info = { type: LGXEnums.DimDatumType.center, data, id: idkey++ };
            rstArr.push(info);
        }

        let position = this.getPos();

        //顶点特征
        let lenth = position.posList.length;
        for (let i = 0; i < lenth; i++) {
            let pt = position.posList[i];
            let data = { idx: i, x: pt.x, y: pt.y }
            let info = { type: LGXEnums.DimDatumType.vertex, data, id: idkey++ };
            rstArr.push(info);
        }

        //线中心特征
        let prePt = position.posList[0];
        for (var i = 1; i < lenth; i++) {
            let cntPt = position.posList[i];
            let x = (prePt.x + cntPt.x) / 2;
            let y = (prePt.y + cntPt.y) / 2;
            let data = { stIdx: i - 1, endIdx: i, x, y };
            let info = { type: LGXEnums.DimDatumType.midpt, data, id: idkey++ };
            rstArr.push(info);
            prePt = cntPt;
        }

        //尾和头顶点
        {
            let cntPt = position.posList[0];
            let x = (prePt.x + cntPt.x) / 2;
            let y = (prePt.y + cntPt.y) / 2;
            let data = { stIdx: lenth - 1, endIdx: 0, x, y };
            let info = { type: LGXEnums.DimDatumType.midpt, data, id: idkey++ };
            rstArr.push(info);
        }

        //每条线段特征
        prePt = position.posList[0];
        for (var i = 1; i < lenth; i++) {
            let cntPt = position.posList[i];
            let st = { x: prePt.x, y: prePt.y };
            let end = { x: cntPt.x, y: cntPt.y };
            let data = { stIdx: i - 1, endIdx: i, st, end };
            let info = { type: LGXEnums.DimDatumType.edge, data, id: idkey++ };
            rstArr.push(info);
            prePt = cntPt
        }
        //尾和头顶点
        {
            let cntPt = position.posList[0];
            let st = { x: prePt.x, y: prePt.y };
            let end = { x: cntPt.x, y: cntPt.y };
            let data = { stIdx: lenth - 1, endIdx: 0, st, end };
            let info = { type: LGXEnums.DimDatumType.edge, data, id: idkey++ };
            rstArr.push(info);
        }

        return rstArr;
    }

    onChgDimValue(dimGraph, oldValue, newValue) {
        console.log("rect graph onChgDimValue******");
        let svc = new RectDimChg(this);
        svc.onChgDimValue(dimGraph, oldValue, newValue);
    }

    onDimBaseChged(dimGraph) {
        console.log("rect onDimBaseChged******");
        let svc = new RectDimBaseChange(this);
        svc.onBaseChanged(dimGraph);
    }

    setTitleZoneFlag(v) { this.titleZoneFlag = v; }
    getTitleZoneFlag() { return this.titleZoneFlag; }

    setSymbolEdgeFlag(v) { this.symbolEdgeFlag = v; }
    getSymbolEdgeFlag() { return this.symbolEdgeFlag; }

    getLocalOrigin(){
        let pt = this.getZone().getCnt();
        return pt;
    }

    clipFillZone_ex(map,mapInfo){
        map.clip();
        map.beginPath();
        var position = this.getPosCopy();
        var lenth = position.posList.length;
        var pt = position.posList[0];
        var p0 = CoordTRFUtil.world2Screen(pt, mapInfo);

        map.moveTo(p0.x, p0.y);
        for (var i = 1; i < lenth; i++) {
            pt = position.posList[i];
            var p = CoordTRFUtil.world2Screen(pt, mapInfo);
            map.lineTo(p.x, p.y);
        }
        map.lineTo(p0.x, p0.y);
        map.closePath();
        return 1;
    }

    //复制粘贴时，从复制源对象复制属性到本图形对应属性----虚函数，由实体继承类实现
    copySubPropFromBuf(bufInfo,tx,ty){
        this.copyCommnonPropFromBuf(bufInfo,tx,ty);
    }

    //检测point点是否落在当前图形对象的边界上
    chPtOnEdge(point,scaling){
        let flag = false;
        let mindis = -1;
        let linesec = new LXCOM.LGXLineSection();
        let interPoint = { x: 0, y: 0 };
        let position = this.getPosCopy();
        let p0 = position.posList[0];
        position.addPoint(p0);
        let lenth = position.posList.length;
        for (let i = 1; i < lenth; i++) {
            let p1 = position.posList[i];
            linesec.setPt(p0, p1);
            let tmpPt = { x: 0, y: 0 };
            let dis = funcs.pt2LineSec(point,linesec,tmpPt);
            if (dis >= 0){
                if (mindis < 0){
                    mindis = dis;
                    interPoint.x = tmpPt.x;
                    interPoint.y = tmpPt.y;
                }
                else if (mindis > dis){
                    mindis = dis;
                    interPoint.x = tmpPt.x;
                    interPoint.y = tmpPt.y;
                }
            }
            p0 = p1;
        }

        if (mindis >= 0 && (mindis*scaling < global.SelectGap)){
            flag = true;
        }
        return flag;
    }
}

export default { RectGraph }
